﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using WindowsGame.Data;
using WindowsGame.Enums;
using WindowsGame.GameObjects;
using WindowsGame.Library;
using WindowsGame.Static;

namespace WindowsGame.Manager
{
	/// <summary>
	/// ScreenManager is responsible for managing all screens in game.
	/// </summary>
	public interface IScreenManager
	{
		void LoadContent();
		void UnloadContent();
		void Update(GameTime gameTime);
		void Draw();
	}

	public class ScreenManager : IScreenManager
	{
		private readonly IDataManager dataManager;
		private readonly IGameObjectManager gameObjectManager;
		private readonly IInputManager inputManager;

		public ScreenManager(IDataManager dataManager, IGameObjectManager gameObjectManager, IInputManager inputManager)
		{
			this.dataManager = dataManager;
			this.gameObjectManager = gameObjectManager;
			this.inputManager = inputManager;
		}

		public void LoadContent()
		{
			Assets.LoadContent();
			LoadData();
		}
		public void UnloadContent()
		{
			Engine.Content.Unload();
		}

		// Update each game object using GameObjectManager.
		public void Update(GameTime gameTime)
		{
			inputManager.Update(gameTime);
			Boolean escape = inputManager.Escape();
			if (escape)
			{
				Engine.Game.Exit();
				return;
			}

			Boolean load = inputManager.Load();
			if (load)
			{
				LoadData();
				return;
			}

			Boolean next = inputManager.Next();
			if (next)
			{
				gameObjectManager.UpdateSpaceship();
				gameObjectManager.UpdateData();
				return;
			}
			Boolean prev = inputManager.Prev();
			if (prev)
			{
				gameObjectManager.UpdateWeapon();
				gameObjectManager.UpdateData();
				return;
			}

			// ORDER: brake, shoot, rotate, thrust.
			TimeSpan elapsedTime = gameTime.ElapsedGameTime;
			TimeSpan time = gameTime.TotalGameTime;

			Direction direction = inputManager.Rotate();
			Boolean thrust = inputManager.Thrust();
			Boolean brake = inputManager.Brake();
			Boolean shoot = inputManager.Shoot();

			gameObjectManager.Update(elapsedTime, time, direction, thrust, brake, shoot);
		}

		// Draw each game object using GameObjectManager.
		public void Draw()
		{
			Engine.GraphicsDevice.Clear(Color.Black);

			// Stars.
			Engine.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Opaque);
			Engine.GraphicsDevice.DepthStencilState = DepthStencilState.DepthRead;
			Engine.SpriteBatch.Draw(Assets.StarTexture, Vector2.Zero, Color.White);
			Engine.SpriteBatch.End();

			// Nebula.
			Engine.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);
			Engine.SpriteBatch.Draw(Assets.NebulaTexture, Vector2.Zero, Color.White);
			Engine.SpriteBatch.End();

			Engine.GraphicsDevice.BlendState = BlendState.Opaque;
			Engine.GraphicsDevice.DepthStencilState = DepthStencilState.Default;

			// Spaceship.
			gameObjectManager.Draw();

			Engine.SpriteBatch.Begin(SpriteSortMode.Texture, BlendState.AlphaBlend);
			Engine.SpriteBatch.DrawString(Assets.MainFont, "Spaceship Demo", new Vector2(50, 50), Color.Yellow);
			Engine.SpriteBatch.End();
		}

		private void LoadData()
		{
			String fldr = GetFldr();
			String offsetsFile		= GetPath("Offsets.xml");
			String spaceshipsFile	= "Spaceships.xml";
			String weaponsFile		= "Weapons.xml";
			String spaceshipFile	= GetPath("Spaceship.txt");
			String weaponFile		= GetPath("Weapon.txt");

			String[] files = new[] { offsetsFile, spaceshipsFile, weaponsFile, spaceshipFile, weaponFile };
			AllData data = dataManager.LoadData(fldr, files);

			gameObjectManager.LoadData(data);
		}

		private static String GetFldr()
		{
			return GetPath(Constants.DATA_DIRECTORY, String.Empty);
		}
		private static String GetPath(String name)
		{
			return GetPath(Constants.DATA_DIRECTORY, name);
		}
		private static String GetPath(String fldr, String name)
		{
			String root = String.Empty;
			String path = String.Format("{0}/{1}/{2}", Constants.ROOT_DIRECTORY, fldr, name);

			return String.Format("{0}{1}", root, path);
		}
	}
}